import DeckResponse from "./types/DeckResponse";
import DrawCardsResponse from "./types/DrawCardsResponse";
import Suit from "../types/Suit";
import Value from "../types/Value";

class DeckApi {

    #baseUrl: string = 'https://deckofcardsapi.com/api/';

    #deckId?: string;

    async shuffle(suits?: Suit[]): Promise<DeckResponse> {
        let deckResponse: DeckResponse = await this.#get<DeckResponse>('/deck/new/shuffle', {
            deck_count: 1,
            ...this.#getCardsParam(suits),
        });

        this.#deckId = deckResponse.deck_id;

        return deckResponse;
    }

    #getCardsParam(suits?: Suit[]) {
        if (!suits) {
            return null;
        }

        return {
            cards: this.getCards(suits),
        };
    }

    private getCards(suits: Suit[]) {
        return suits.flatMap(suit => {
            return Value.ALL_VALUES.map(value => value.code + suit.code);
        });
    }

    async drawCards(count: number = 1): Promise<DrawCardsResponse> {
        let drawCardsResponse: DrawCardsResponse = await this.#get<DrawCardsResponse>(`/deck/${this.#deckId}/draw`, {
            count,
        });

        this.#deckId = drawCardsResponse.deck_id;

        return drawCardsResponse;
    }

    async #get<T>(url: string, params?: Record<string, any>): Promise<T> {
        let response = await fetch(this.#baseUrl + url + '?' + new URLSearchParams(params));

        return await response.json();
    }
}

const deckApi = new DeckApi();

export default deckApi;
